﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FlatRedBall;
using FlatRedBall.Graphics;
using FlatRedBall.Math.Geometry;
using Microsoft.Xna.Framework;
using HarpoonMan.Utilities;
using HarpoonMan.WorldObjects;
using FlatRedBall.Input;

namespace HarpoonMan.PlayerObjects
{
    public enum HarpoonState
    {
        Grabbed,
        Throwing,
        Crashed,
        Retracting,
        Idle
    }

    public class Harpoon : PositionedObject
    {
        #region Variables
        private AxisAlignedRectangle _collision;
        private string _contentManager;

        private Sprite _sprite;
        private Vector3 _throwTo;

        private const float SPEED = 35.0f;
        #endregion

        #region Properties
        public Vector3 ThrowVector
        {
            set { _throwTo = value; }
        }

        public HarpoonState State
        {
            get;
            set;
        }

        public AxisAlignedRectangle Collision
        {
            get { return _collision; }
        }

        public bool Visible
        {
            get { return _sprite.Visible; }
            set { _sprite.Visible = value; }
        }

        public Box AttachedBox
        {
            get;
            set;
        }

        #endregion

        #region Methods
        public Harpoon(string newContentManager) : base()
        {
            Initialize(true);

            _contentManager = newContentManager;
        }


        protected virtual void Initialize(bool addToManagers)
        {
            // Here you can preload any content you will be using
            // like .scnx files or texture files.
            if (addToManagers)
            {
                AddToManagers(null);
            }
        }

        public virtual void AddToManagers(Layer layerToAddTo)
        {
            SpriteManager.AddPositionedObject(this);

            _sprite = SpriteManager.AddSprite(@"Content/Player/Harpoon/Harpoon0000");
            _sprite.PixelScale();
            _sprite.ScaleX *= .5f;
            _sprite.ScaleY *= .5f;
            _sprite.Visible = false;
            _sprite.AttachTo(this, false);

            _collision = ShapeManager.AddAxisAlignedRectangle();
            _collision.RelativePosition.X += 2.0f;
            _collision.ScaleX = _sprite.ScaleX * .3f;
            _collision.ScaleY = _sprite.ScaleX * .15f;
            _collision.AttachTo(this, false);

            _collision.Visible = false;

            State = HarpoonState.Idle;
        }

        public virtual void Activity()
        {
            if (State == HarpoonState.Throwing && Velocity.Equals(Vector3.Zero))
            {
                if (!_throwTo.Equals(Vector3.Zero))
                {
                    _throwTo.Normalize();
                    Velocity = _throwTo * SPEED;
                    Acceleration.Y = GameManager.GRAVITY;
                }
            }
            else if (State == HarpoonState.Throwing)
            {
                FaceMovementDirection();
            }
            else if (State == HarpoonState.Grabbed)
            {
                _throwTo = Vector3.Zero;
                Velocity = Vector3.Zero;
                Acceleration = Vector3.Zero;
            }
            else if (State == HarpoonState.Crashed)
            {
                _throwTo = Vector3.Zero;
                Velocity = Vector3.Zero;
                Acceleration = Vector3.Zero;
            }
        }

        public virtual void Retract(Vector3 retractTo)
        {
            retractTo.Normalize(); 
            Velocity = retractTo * SPEED;
        }

        public virtual void Destroy()
        {
            SpriteManager.RemovePositionedObject(this);

            SpriteManager.RemoveSprite(_sprite);
            ShapeManager.Remove(_collision);
        }

        #endregion

        #region Private Methods
        private void FaceMovementDirection()
        {
            float faceAtX = Velocity.X;
            float faceAtY = Velocity.Y;

            float rotation = (float)Math.Atan2(faceAtY, faceAtX);

            this.RotationZ = rotation;
        }
        #endregion

        public void DropBox()
        {
            if (AttachedBox != null)
            {
                AttachedBox.Detach();
                AttachedBox = null;
            }
        }
    }
}
